import { useState } from 'react'
/**
 * 单一功能原理
 *
 * 随着时间推移 保持不变？如此，便不是 state。
 * 通过 props 从父组件传递？如此，便不是 state。
 * 是否可以基于已存在于组件中的 state 或者 props 进行计算？如此，它肯定不是state！
 *
 * 验证 state 应该被放置在哪里
 */

/**
 *
 * @param {*} param0
 * @returns
 */
function ProductCategoryRow({ category }) {
  'use no memo'
  return (
    <tr>
      <th colSpan="2">{category}</th>
    </tr>
  )
}
function ProductRow({ product }) {
  return (
    <tr>
      <td>{product.name}</td>
      <td>{product.price}</td>
    </tr>
  )
}
function ProductTable({ filterText, inStockOnly, products }) {
  const showProduct = products.filter((p) => {
    let flag = true
    if (filterText) {
      flag = p.name.toLowerCase().indexOf(filterText.toLowerCase()) > -1
    }
    if (inStockOnly) {
      flag = p.stocked
    }
    return flag
  })
  const categorys = new Set(
    showProduct.map((item) => {
      return item.category
    }),
  )

  const nodes = Array.from(categorys)
    .map((c) => {
      return [{ isCategory: true, value: c }, ...showProduct.filter((p) => c == p.category)]
    })
    .flat()
    .map((row, index) => {
      return row.isCategory ? <ProductCategoryRow category={row.value} key={index} /> : <ProductRow product={row} key={index} />
    })

  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Price</th>
        </tr>
      </thead>
      <tbody>{nodes}</tbody>
    </table>
  )
}
function SearchBar({ filterText, inStockOnly, onFilterTextChange, onInStockOnlyChange }) {
  /**
   * 不提供onChange事件，浏览器不会更新 input value
   */
  return (
    <form>
      <input type="text" value={filterText} placeholder="Search..." onChange={(e) => onFilterTextChange(e.target.value)} />
      <label>
        <input type="checkbox" checked={inStockOnly} onChange={(e) => onInStockOnlyChange(e.target.checked)} /> Only show products in stock
      </label>
    </form>
  )
}

function FilterableProductTable({ products }) {
  const [filterText, setFilterText] = useState('')
  const [inStockOnly, setInStockOnly] = useState('')

  return (
    <div>
      <SearchBar
        filterText={filterText}
        inStockOnly={inStockOnly}
        onFilterTextChange={setFilterText}
        onInStockOnlyChange={setInStockOnly}
      />
      <ProductTable filterText={filterText} inStockOnly={inStockOnly} products={products} />
    </div>
  )
}
const PRODUCTS = [
  { category: 'Fruits', price: '$1', stocked: true, name: 'Apple' },
  { category: 'Fruits', price: '$1', stocked: true, name: 'Dragonfruit' },
  { category: 'Fruits', price: '$2', stocked: false, name: 'Passionfruit' },
  { category: 'Vegetables', price: '$2', stocked: true, name: 'Spinach' },
  { category: 'Vegetables', price: '$4', stocked: false, name: 'Pumpkin' },
  { category: 'Vegetables', price: '$1', stocked: true, name: 'Peas' },
]
export default function App() {
  return <FilterableProductTable products={PRODUCTS} />
}
